package org.lexicon.swpogo

import com.hp.hpl.jena.rdf.model.Resource;
import java.util.List;
import java.net.URI;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.shared.PrefixMapping;
import java.util.UUID;
import com.hp.hpl.jena.rdf.model.AnonId;


class DefaultSemWebPogo implements SemWebPogo {

	/*
	 * Popular vocabularies
	 * foaf, dublin core, rdf, rdfs, owl, goodrelations, schema.org 
	 */
	
	static rdfPrefixMappings = [foaf: "http://xmlns.com/foaf/0.1/",
								rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
								rdfs: "http://www.w3.org/2000/01/rdf-schema#",
								owl: "http://www.w3.org/2002/07/owl#",
								dc: "http://purl.org/dc/elements/1.1/",
								dcterms: "http://purl.org/dc/terms/",
								gr: "http://purl.org/goodrelations/v1#",
								schema: "http://schema.org/"]
	
	static rdfBasicClassMappings = []
	static rdfBasicPropertyMappings = [:]
	static classNamespace = "http://"
	
	SemWebPropertyBinding[] semWebPropertyBindings
	def rdfPropertyBindings = [:]
	RdfModelMarshaller rdfModelMarshaller
	URI namespace
	URI uri
	Model model
	
	def rdfSubject = {
		if(this.uri != null) {
			ModelFactory.createDefaultModel().createResource(AnonId.create())
		}
		else {
			ModelFactory.createDefaultModel().createResource(this.uri.toString())
		}
	}
	
	def rdfType = {
		if (this.class.rdfPrefixMappings.containsKey(rdf)) {
			this.model.createProperty(this.class.rdfPrefixMappings.get("rdf") + "type")
		}
		else {
			this.model.createProperty("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")
		}
	}
	
	def fullUri = {it ->
		this.class.rdfMappings.get(it.split(":")[0]) + it.split(":")[1]
	}
			
	public DefaultSemWebPogo() {
		super()
		this.init()
	}
	
	public void init() {
		rdfModelMarshaller = new DefaultRdfModelMarshaller()
		
		//for each basic property mapping create a default property binding
		this.class.rdfBasicPropertyMappings.each() {
			this.addSimpleRdfPropertyBinding(it.key, new DefaultRdfPropertyBinding(it.key, it.value))				
		}
		
		//property change listener
		this.metaClass = new SemWebPogoPropertyChangeMetaClass(this.metaClass);
		if (this.uri == null) {
			this.uri = this.createUri()
		}
		this.initialiseModel()
		
	}
	
	//initialises the underlying RDF model
	public void initialiseModel() {
		this.model = ModelFactory.createDefaultModel().add(this.model.createClassModel())
	}
	
	//this creates the RDF model from the type mappings
	public Model createClassModel() {
		Model classModel = ModelFactory.createDefaultModel()
		model.add(classModel.createStatement(classModel.createResource(rdfSubject,rdfType,)))
	}
	
	//method for creating a new uri when one is not specified on construction
	public URI createUri() {
		return new URI(new UUID())
	}
	
	//update the underlying RDF model when the instance uri changes
	public void updateUri(URI oldValue, URI newValue) {
		this.model.listStatements(this.model.createResource(oldValue.toString()), null, null).each() {
			this.model.add(this.model.createStatement(this.model.createResource(newValue.toString), it.getPredicate(), it.getObject()))
			this.model.remove(it)
		}
	}
	
	public URI getUri() {
		return this.uri
	}
	
	public void setUri(URI uri) {
		this.uri = uri
	}
	
	public void setUri(String uri) {
		this.uri = new URI(uri)
	}
	
	public void addPrefixMapping(String prefix, String namespace) {
		this.model.setNsPrefix(prefix, namespace)
	}
	
	public void removePrefixMapping(String prefix) {
		this.model.removeNsPrefix(prefix)
	}
	
	public PrefixMapping getPrefixMapping() {
		return this.model.getNsPrefixMap()
	}
	
	public void setPrefixMapping(PrefixMapping prefixMapping){
		this.model.setNsPrefixes(prefixMapping)
	}
	
	public Model marshall() {
		return this.rdfModelMarshaller.marshall(this)
	}
	
	public void unmarshall(Model model) {
		this.rdfModelMarshaller.unmarshall(this, model)
	}

	public SparqlQueryBuilder getSparqlQueryBuilder() {
		
	}
	
	public void setSparqlQueryBuilder(SparqlQueryBuilder sparqlQueryBuilder) {
		
	}
	
	public Provenance getProvenance() {
		
	}
	public void setProvenance(Provenance provenance){
		
	}
	
	public void setRdfModelMarshaller(RdfModelMarshaller rdfModelMarshaller) {
		this.rdfModelMarshaller = rdfModelMarshaller
	}
	public RdfModelMarshaller getRdfModelMarshaller(){
		return this.rdfModelMarshaller
	}
	
	public void addRdfPropertyBinding(RdfPropertyBinding rdfPropertyBinding){
		
	}
	
	public void addSimpleRdfPropertyBinding(String pogoProperty, String RdfProperty) {
		
	}
	public void addSimpleRdfPropertyBinding(String pogoProperty, String RdfProperty, String Namespace) {
		
	}
	
	public void removeRdfPropertyBinding(String pogoProperty) {
		
	}
	
	public List<SemWebPropertyBinding> getRdfPropertyBindings() {
		
	}
	
	public void addTypeBinding(Resource type){
		
	}
	
	public void removeTypeBinding(Resource type){
		
	}
	
	public List<Resource> getTypeBindings(){
		
	}
	
	public void addTypeBinding(String type) {
		
	}
	public void removeTypeBinding(String type) {
		
	}
	public void addTypeBinding(String type, String namespace) {
		
	}
	
	protected URI getPrefixedUri(String prefixedProperty) {
		return this
	}
	
}
